﻿using System;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Workflow;
using System.Linq.Expressions;
using System.Collections.Generic;
using T2V.SharePoint.Common.Utilities.Camlex;
using T2V.SharePoint.Common.Utilities;
using PepsiCo.Common;
using Microsoft.SharePoint.Administration;

namespace PepsiCo.Intranet.Receivers.BannerER
{
    /// <summary>
    /// List Item Events
    /// </summary>
    public class BannerER : SPItemEventReceiver
    {
       /// <summary>
       /// An item is being added.
       /// </summary>
       public override void ItemAdding(SPItemEventProperties properties)
       {
           base.ItemAdding(properties);

           SPWeb spWeb = properties.Web;
           spWeb.AllowUnsafeUpdates = false;

           try
           {
               IncreaseItemOrderNo(properties);

               TrimTextFieldValue(properties, PepsiCoConstants.Banner.HYPERLINK_COLUMN);
           }
           catch (Exception ex)
           {
               SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("BannerER ItemAdding", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);
           }
           finally
           {
               spWeb.AllowUnsafeUpdates = true;
           }
       }

       /// <summary>
       /// An item is being updated.
       /// </summary>
       public override void ItemUpdating(SPItemEventProperties properties)
       {
           base.ItemUpdating(properties);

           if (properties.ListItem != null)
           {

               SPWeb spWeb = properties.Web;
               spWeb.AllowUnsafeUpdates = false;

               try
               {
                   IncreaseItemOrderNo(properties);

                   TrimTextFieldValue(properties, PepsiCoConstants.Banner.HYPERLINK_COLUMN);
               }
               catch (Exception ex)
               {
                   SPDiagnosticsService.Local.WriteTrace(0, new SPDiagnosticsCategory("BannerER ItemUpdating", TraceSeverity.Unexpected, EventSeverity.Error), TraceSeverity.Unexpected, ex.Message, ex.StackTrace);
               }
               finally
               {
                   spWeb.AllowUnsafeUpdates = true;
               }
           }
       }

       /// <summary>
       /// An item is being deleted.
       /// </summary>
       public override void ItemDeleting(SPItemEventProperties properties)
       {
           base.ItemDeleting(properties);
       }

       private void IncreaseItemOrderNo(SPItemEventProperties properties)
       {
           SPSecurity.RunWithElevatedPrivileges(delegate()
           {

               using (SPSite spSite = new SPSite(properties.SiteId))
               {
                   //spSite.WebApplication.FormDigestSettings.Enabled = false;

                   using (SPWeb spWeb = spSite.OpenWeb(properties.Web.ID))
                   {

                       spWeb.AllowUnsafeUpdates = true;

                       try
                       {

                           if (properties.AfterProperties[PepsiCoConstants.Banner.ITEM_ORDER_COLUMN] != null && !string.IsNullOrEmpty(properties.AfterProperties[PepsiCoConstants.Banner.ITEM_ORDER_COLUMN].ToString()))
                           {
                               int orderNo = 0;
                               int.TryParse(properties.AfterProperties[PepsiCoConstants.Banner.ITEM_ORDER_COLUMN].ToString(), out orderNo);

                               if (orderNo != 0)
                               {
                                   string strItemId = properties.ListItem == null ? "0" : properties.ListItemId.ToString();

                                   string caml = string.Empty;
                                   var expressionsAnd = new List<Expression<Func<SPListItem, bool>>>();

                                   expressionsAnd.Add(x => ((int)x[PepsiCoConstants.Banner.ITEM_ORDER_COLUMN]) >= orderNo);
                                   expressionsAnd.Add(x => (x["ID"]) != (DataTypes.Counter)strItemId);

                                   caml = Camlex.Query().WhereAll(expressionsAnd).OrderBy(x => x[PepsiCoConstants.Banner.ITEM_ORDER_COLUMN] as Camlex.Asc).ToString();

                                   SPQuery spQuery = new SPQuery();
                                   spQuery.Query = caml;

                                   SPList currentList = spWeb.Lists[properties.List.ID];
                                   SPListItemCollection items = currentList.GetItems(spQuery);

                                   foreach (SPListItem item in items)
                                   {
                                       orderNo++;

                                       using (DisableItemEvent scope = new DisableItemEvent())
                                       {
                                           item[PepsiCoConstants.Banner.ITEM_ORDER_COLUMN] = orderNo;
                                           item.Update();
                                       }
                                   }
                               }
                           }
                           else
                           {
                               using (DisableItemEvent scope = new DisableItemEvent())
                               {
                                   properties.AfterProperties[PepsiCoConstants.Banner.ITEM_ORDER_COLUMN] = GetLatestItemOrderNo(properties) + 1;
                               }
                           }
                       }
                       catch (Exception ex)
                       { }
                       finally {
                           spWeb.AllowUnsafeUpdates = false;
                       }

                   }

                   //spSite.WebApplication.FormDigestSettings.Enabled = true;
               }

           });

       }

       private int GetLatestItemOrderNo(SPItemEventProperties properties)
       {
           int orderNo = 0;

           string caml = string.Empty;
           var expressionsAnd = new List<Expression<Func<SPListItem, bool>>>();

           if (expressionsAnd.Count > 0)
               caml = Camlex.Query().WhereAll(expressionsAnd).OrderBy(x => x[PepsiCoConstants.Banner.ITEM_ORDER_COLUMN] as Camlex.Desc).ToString();
           else
               caml = Camlex.Query().OrderBy(x => x[PepsiCoConstants.Banner.ITEM_ORDER_COLUMN] as Camlex.Desc).ToString();

           SPQuery spQuery = new SPQuery();
           spQuery.Query = caml;

           spQuery.RowLimit = 1;

           SPList currentList = properties.List;
           SPListItemCollection items = currentList.GetItems(spQuery);

           if (items != null && items.Count > 0)
           {
               SPListItem item = items[0];

               if (item != null)
               {
                   orderNo = Convert.ToInt32(item[PepsiCoConstants.Banner.ITEM_ORDER_COLUMN]);
               }
           }

           return orderNo;
       }

       private void TrimTextFieldValue(SPItemEventProperties properties, string fieldName)
       {
           if (properties.AfterProperties[fieldName] != null)
           {
               using (DisableItemEvent scope = new DisableItemEvent())
               {
                   properties.AfterProperties[fieldName] = properties.AfterProperties[fieldName].ToString().Trim();
               }
              
           }
           else
           {
               using (DisableItemEvent scope = new DisableItemEvent())
               {
                   properties.AfterProperties[fieldName] = string.Empty;
               }
           }
       }
    }
}
